#include <FastEspnow_struct.h> // 相关结构体存储库

MESSAGE::MESSAGE(const uint8_t *buf)
{
    // Serial.println("MESSAGE");
    sn = (*(buf + 2) << 8) | *(buf + 3);
    // Serial.println(sn);
    cmd = *(buf + 4);
    // Serial.println(cmd);
    len = *(buf + 5);
    // Serial.println(len);
    for (int i = 0; i < len; i++)
        data[i] = *(buf + i + 6);
    setSum();
}

MESSAGE::MESSAGE(uint16_t _sn, uint8_t _cmd, uint8_t _len, ...)
{
    sn = _sn;
    cmd = _cmd;
    len = _len;

    va_list args;
    va_start(args, _len); // args指向栈顶
    for (int i = 0; i < len; ++i)
    {
        data[i] = va_arg(args, int);
    }
    va_end(args);
    setSum();
}

MESSAGE::MESSAGE(uint16_t _sn, uint8_t _cmd, uint8_t _len, uint8_t *_data)
{
    sn = _sn;
    cmd = _cmd;
    len = _len;
    for (int i = 0; i < _len; i++)
        data[i] = *(_data + i);
    setSum();
}

uint8_t MESSAGE::setSum()
{
    uint8_t t = head[0] + head[1] + (sn >> 8) + sn + cmd + len;
    for (int i = 0; i < len; i++)
        t += data[i];
    sum = t & 0xFF;
    return sum;
}

uint8_t *MESSAGE::toArry()
{
    static uint8_t buf[50];
    buf[0] = head[0];
    buf[1] = head[1];
    buf[2] = sn >> 8;
    buf[3] = sn;
    buf[4] = cmd;
    buf[5] = len;
    for (int i = OFFSET(MESSAGE, data); i < (len + OFFSET(MESSAGE, data)); i++)
        buf[i] = data[i - OFFSET(MESSAGE, data)];
    buf[len + OFFSET(MESSAGE, data)] = sum;
    return buf;
}

uint8_t *peer_info::toArry()
{
    static uint8_t peerBuf[24];
    peerBuf[0] = sn >> 8;
    peerBuf[1] = sn;

    for (int i = 0; i < 6; i++)
        peerBuf[2 + i] = address[i];

    return peerBuf;
}

void CConfig::loadConfigurayion()
{
    // 1. 初始化空间
    this->begin("CConfig");

    // 2. 读取 peer_count 配对设备总数
    peer_count = this->getUInt("peer_count", 0);

    // 3.0 读取 peers 配对列表
    uint8_t buf[peer_count * INFO_LENGTH];
    this->getBytes("peers", buf, sizeof(buf));

    // 3.1 解析 peers 数组
    for (int i = 0; i < peer_count; i++)
    {
        // 3.1.1 获取 sn
        peers[i].sn = (buf[0 + INFO_LENGTH * i] << 8) | buf[1 + INFO_LENGTH * i];
        // 3.1.2 获取 mac 地址
        for (int j = 0; j < 6; j++)
            peers[i].address[j] = buf[2 + j + INFO_LENGTH * i];
    }
}

void CConfig::addPeerToconfig(const uint8_t *mac, uint16_t _sn)
{
    // 1. 如果超出最大存储数量，直接返回
    if (peer_count == MAX_PEERS)
        return;
    // 2. 赋值 mac 地址
    for (int i = 0; i < 6; i++)
        peers[peer_count].address[i] = mac[i];
    // 3.赋值 sn
    peers[peer_count].sn = _sn;
    // 6. 配对数量+1
    peer_count++;

    // 7. 将peer[] 转化成数组 buf 注意！ buf的名称要和构造函数中的一致
    uint8_t buf[peer_count * INFO_LENGTH];

    for (int i = 0; i < peer_count; i++)
    {
        uint8_t *p = peers[i].toArry();
        for (int j = 0; j < INFO_LENGTH; j++)
            buf[i * INFO_LENGTH + j] = *(p + j);
    }

    // 8. 存储数组
    this->putBytes("peers", buf, sizeof(buf));
    this->putUInt("peer_count", peer_count);
}

void CConfig::addPeerToconfig(peer_info p)
{
    addPeerToconfig(p.address, p.sn);
}

int CConfig::findPeer(const uint8_t *peerMAC)
{
    for (int i = 0; i < peer_count; i++)
    {
        for (int j = 0; j < 6; j++)
            if (peerMAC[j] != peers[i].address[j])
                continue;

        if (peerMAC[0] == peers[i].address[0] && peerMAC[1] == peers[i].address[1] && peerMAC[2] == peers[i].address[2] && peerMAC[3] == peers[i].address[3] && peerMAC[4] == peers[i].address[4] && peerMAC[5] == peers[i].address[5])
            return i;
    }
    return -1;
}

int CConfig::findPeer(uint16_t sn)
{
    for (int i = 0; i < peer_count; i++)
    {
        if (sn == peers[i].sn)
            return i;
    }
    return -1;
}

void CConfig::removePeerToconfig(uint8_t index)
{
    if (peer_count == 0)
        return;
    // 1. 把 peers 列表中，index 之后的数据， 往前挪一位
    for (int p = index; p < peer_count; p++)
    {
        for (int a = 0; a < 6; a++)
            peers[p].address[a] = peers[p + 1].address[a]; // 挪动 mac地址
        peers[p].sn = peers[p + 1].sn;                     // 挪动 sn
    }

    // 2. 擦除最后一个条目
    memset(peers[peer_count].address, 0, 6);
    peers[peer_count].sn = 0;
    // 3. 配对数量-1
    peer_count--;

    // 4. 将peer[] 转化成数组 buf 注意！ buf的名称要和构造函数中的一致
    uint8_t buf[peer_count * INFO_LENGTH];

    for (int i = 0; i < peer_count; i++)
    {
        uint8_t *p = peers[i].toArry();
        for (int j = 0; j < INFO_LENGTH; j++)
            buf[i * INFO_LENGTH + j] = *(p + j);
    }

    // 5. 存储数组
    this->putBytes("peers", buf, sizeof(buf));
    this->putUInt("peer_count", peer_count);
}

void CConfig::clearAllPeersOnconfig()
{
    peer_count = 0;
    this->putUInt("peer_count", peer_count);
}